﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.UI;
using System.Web.UI.WebControls;
using ScrewTurn.Wiki;
using System.Text.RegularExpressions;
using System.Data.SqlClient;
using ScrewTurn.Wiki.PluginFramework;
using System.Collections;

public partial class AddComponent : BasePage
{
	protected void Page_Load(object sender, EventArgs e)
	{
		#region Verify Authentication
		// Re-verify authentication
		PageInfo pageInfo = Pages.Instance.FindPage(Request["Page"]);
		if (pageInfo == null)
		{
			// Page creation
			if (SessionFacade.LoginKey == null && !Settings.PublicAccess)
			{
				Response.Redirect("Login.aspx?Redirect=Experiments.aspx");
			}
			if (!Settings.UsersCanCreateNewPages && !SessionFacade.Admin)
			{
				Response.Redirect("AccessDenied.aspx");
			}
		}
		else
		{
			// Page modification
			if (pageInfo.Provider.ReadOnly) Response.Redirect(pageInfo.Name + Settings.PageExtension);

			if (pageInfo.Status == PageStatus.Locked)
			{
				if (SessionFacade.LoginKey == null || (SessionFacade.LoginKey != null && (SessionFacade.LoginKey == null || !SessionFacade.Admin)))
				{
					Response.Redirect("AccessDenied.aspx");
				}
			}

			// Login/Authorization check
			if (SessionFacade.LoginKey == null && !Settings.PublicAccess && pageInfo.Status != PageStatus.Public)
			{
				Response.Redirect("Login.aspx?Redirect=" + Tools.UrlEncode(Request.Url.ToString().Substring(Request.Url.ToString().ToLowerInvariant().IndexOf("Experiments.aspx"))));
			}
			if ((Settings.PublicAccess || pageInfo.Status == PageStatus.Public) && SessionFacade.LoginKey == null)
			{
				//lblIpLogged.Visible = true;
			}
		}
		#endregion

		if (Request["CompType"] == null)
		{
			Response.Redirect("~/DesignExperiment.aspx");
		}

		switch (Request["CompType"])
		{
			case "pp":
				lblTitle.Text = "Add Pulse Program";
				break;
			case "ws":
				lblTitle.Text = "Add Wave Shape";
				break;
			case "cpd":
				lblTitle.Text = "Add CPD";
				break;
			case "scr":
				lblTitle.Text = "Add Script";
				panScriptType.Visible = true;
				break;
			default:
				Response.Redirect("~/DesignExperiment.aspx");
				break;
		}

		tbType.MaxLength = Constants.TypeLength;
		tbContent.MaxLength = Constants.ContentLength;
		tbName.MaxLength = Constants.NameLength;
		tbMemo.MaxLength = Constants.MemoLength;
	}

	/// <summary>
	/// Custom validator that checks whether there is <script> tag in the text input
	/// </summary>
	protected void ValidateForScripts(object source, ServerValidateEventArgs args)
	{
		args.IsValid = !Regex.IsMatch(args.Value.ToString(), @"\<script.*?\>");
	}

	protected void ValidateAuthorsNumber(object source, ServerValidateEventArgs args)
	{
		args.IsValid = (int.Parse(args.Value) < 1) ? false : true;
	}

	/// <summary>
	/// Clears form fields
	/// </summary>
	protected void butClear_Click(object sender, EventArgs e)
	{
		tbName.Text = "";
		tbMemo.Text = "";
		tbContent.Text = "";
		tbType.Text = "";
		AuthorsList.Clear();
	}

	protected void butSubmit_Command(object sender, CommandEventArgs e)
	{
		if (!Page.IsValid) return;

		string tablename = "";	// Used in constraction of DB queries; assigned once in the next switch statement
		string Category = "";	// Used to categorize new wiki page
		switch (Request["CompType"])
		{
			case "pp":
				tablename = "pulseprograms";
				Category = "Pulse Program";
				break;
			case "ws":
				tablename = "waveshapes";
				Category = "Wave Shape";
				break;
			case "cpd":
				tablename = "cpds";
				Category = "CPD Scheeme";
				break;
			case "scr":
				tablename = "scripts";
				Category = "Script";
				break;
			default:
				Response.Redirect("~/DesignExperiment.aspx");
				break;
		}

		string LastInsertedFieldID; // Keeps the ID of newly created DB entry for the component, used to add relation with authors

		// Adding new component into the database
		using (SqlConnection NMRExperimentsConnection = new SqlConnection(Constants.NMRExperimentsConStr))
		{
			NMRExperimentsConnection.Open();

			using (SqlCommand QueryInsertComponent = NMRExperimentsConnection.CreateCommand())
			{
				QueryInsertComponent.CommandText =
@"INSERT INTO ##table## (name, memo, content, version, versionupdateinfo, firstversionid, previousversionid)
VALUES        (@name, @memo, @content, @version, @versioninfo, @firstversionid, @prevversionid )
SELECT @@IDENTITY".Replace("##table##", tablename);

				QueryInsertComponent.Parameters.Add(new SqlParameter("@name", tbName.Text));
				QueryInsertComponent.Parameters.Add(new SqlParameter("@memo", tbMemo.Text));
				QueryInsertComponent.Parameters.Add(new SqlParameter("@content", tbContent.Text));
				QueryInsertComponent.Parameters.Add(new SqlParameter("@version", "1"));
				QueryInsertComponent.Parameters.Add(new SqlParameter("@versioninfo", "Original Release"));
				QueryInsertComponent.Parameters.Add(new SqlParameter("@firstversionid", "1"));
				QueryInsertComponent.Parameters.Add(new SqlParameter("@prevversionid", "1"));

				LastInsertedFieldID = QueryInsertComponent.ExecuteScalar().ToString();

				// For first version it is easy @firstversionid and @prevversionid are equal to Auto-generated ID
				// Therefor UPDATE query changes these values according to LastInsertedFieldID
				QueryInsertComponent.CommandText =
@"UPDATE       ##table##
SET                firstversionid = @Id, previousversionid = @Id
WHERE        (id = @Id)".Replace("##table##", tablename);

				QueryInsertComponent.Parameters.Add(new SqlParameter("@Id", LastInsertedFieldID));

				QueryInsertComponent.ExecuteScalar();

				QueryInsertComponent.Parameters.Clear();
				if (tablename == "scripts")
				{
					QueryInsertComponent.CommandText =
@"UPDATE scripts
SET type = @Type
WHERE (id=@Id)";
					QueryInsertComponent.Parameters.Add(new SqlParameter("@Id", LastInsertedFieldID));
					QueryInsertComponent.Parameters.Add(new SqlParameter("@Type", tbType.Text));

					QueryInsertComponent.ExecuteScalar();
				}
			}

			string currentAuthorID = null; // Used to keep newly added authors ID

			foreach (DictionaryEntry x in AuthorsList.SelectedAuthors)
			{
				currentAuthorID = (string)x.Key;

				if (x.Value is Authors.Author)   // Means name is new, needs to be added to DB
				{
					Authors.Author cAuthor = (Authors.Author)x.Value;
					using (SqlCommand QueryInsertNewAuthor = NMRExperimentsConnection.CreateCommand())
					{
						QueryInsertNewAuthor.CommandText =
@"INSERT INTO authors  (authfn, authmn, authln)
 VALUES (@fn, @mn, @ln)
SELECT @@IDENTITY";

						QueryInsertNewAuthor.Parameters.Add(new SqlParameter("@fn", cAuthor.FirstName));
						QueryInsertNewAuthor.Parameters.Add(new SqlParameter("@mn", cAuthor.MiddleName));
						QueryInsertNewAuthor.Parameters.Add(new SqlParameter("@ln", cAuthor.LastName));

						currentAuthorID = QueryInsertNewAuthor.ExecuteScalar().ToString();
					}
				}

				using (SqlCommand QueryInsertAuthorsComponentRelation = NMRExperimentsConnection.CreateCommand())
				{
					QueryInsertAuthorsComponentRelation.CommandText =
@"INSERT INTO relation_##firstforeignkeyreftable##_to_##secondforeignkeyreftable## 
VALUES (@FieldID, @AuthorID, @AuthorNumber)"
.Replace("##firstforeignkeyreftable##", tablename).Replace("##secondforeignkeyreftable##", "authors");

					QueryInsertAuthorsComponentRelation.Parameters.Add(new SqlParameter("@FieldID", LastInsertedFieldID));
					QueryInsertAuthorsComponentRelation.Parameters.Add(new SqlParameter("@AuthorID", currentAuthorID));
					QueryInsertAuthorsComponentRelation.Parameters.Add(new SqlParameter("@AuthorNumber", Convert.ToString(AuthorsList.SelectedAuthors.GetIndexOf(x.Key))));

					QueryInsertAuthorsComponentRelation.ExecuteScalar();
				}
			}
		}

		UniBasel.Biozentrum.NMR.NMRGenUtils.createWikiPage(Category, LastInsertedFieldID, tbName.Text);

		Response.Redirect("~/Experiments.aspx?CompType=" + Request["CompType"]);
	}
}
